package com.synjones.handsetS8L;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Handler;

import com.IDWORLD.LAPI;
import com.synjones.cardutil.util;

import java.util.HashMap;
import java.util.Iterator;

public class LDFpUsbModule implements FingerprintReaderInterface {

    private static volatile LDFpUsbModule mInstance;
    private LAPI m_cLAPI = null;
    private int m_hDevice = 0;
    Handler outHandler;
    private byte[] fingerTemplate;
    Activity activity;

    private LDFpUsbModule(Activity activity,Handler handler) {
        m_cLAPI = new LAPI(activity);
        outHandler=handler;
        this.activity=activity;
    }

    private void sendMsg(int what,Object msg){
        if(outHandler!=null)
            outHandler.obtainMessage(what,msg).sendToTarget();
    }

    public static LDFpUsbModule getInstance(Activity activity,  Handler handler) {
        if (mInstance == null) {
            synchronized (LDFpUsbModule.class) {
                if (mInstance == null) {
                    mInstance = new LDFpUsbModule(activity,handler);
                }
            }
        }
        return mInstance;
    }


    @Override
    public void powerOn() {
        PowerUtil.powerFinger ("1");
        PowerUtil.powerUsb("1");
        util.mSleep(1000);
        requestPermission();
    }

    @Override
    public void powerOff() {
        PowerUtil.powerFinger ("0");
        PowerUtil.powerUsb("0");
    }

    @Override
    public int open() {

        m_hDevice=m_cLAPI.OpenDeviceEx();
        if(m_hDevice==0) return -1;
        return 0;
    }

    public void requestPermission() {
        UsbManager usbManager = (UsbManager) activity.getSystemService(Context.USB_SERVICE);
        UsbDevice usbDevice = enumerateDevice(usbManager);
        if(usbDevice==null) return;
        if (usbManager.hasPermission(usbDevice)) {

        } else {
            PendingIntent comm = PendingIntent.getBroadcast(this.activity, 0, new Intent("com.IDWORLD.USB_PERMISSION"), 0);
            usbManager.requestPermission(usbDevice, comm);
        }
    }


    private UsbDevice enumerateDevice(UsbManager usbManager) {
        if(usbManager != null) {
            HashMap deviceList = usbManager.getDeviceList();
            if(!deviceList.isEmpty()) {
                StringBuffer sb = new StringBuffer();
                Iterator var4 = deviceList.values().iterator();

                while(true) {
                    while(var4.hasNext()) {
                        UsbDevice device = (UsbDevice)var4.next();
                        if(device.getVendorId() == 1155 && device.getProductId() == 22288) {
                            return device;
                        }
                    }

                    return null;
                }
            }
        }
        return null;
    }


    @Override
    public int close() {
        int ret=m_cLAPI.CloseDeviceEx(m_hDevice);
        m_hDevice=0;
        return ret==1?0:1;
    }

    @Override
    public int cleanFpFeature() {
        fingerTemplate = null;
        return 0;
    }

    private boolean checkOpen(){
        if(m_hDevice==0){
            sendMsg(MESSAGE_UPDATE_STATUS,"指纹模块未打开");
            return false;
        }
        return true;
    }

    volatile boolean isScaning=false;
    static final int IMAGE_THRESHOLD = 40;
    static final int VERIFY_THRESHOLD = 60;
    @Override
    public FpFeature getFpFeature(boolean showFpImage,long timeout) {
        if(!checkOpen()) return null;
        isScaning=true;
        byte[] m_imageBest = new byte[LAPI.WIDTH*LAPI.HEIGHT];
        byte[] m_imageTmp = new byte[LAPI.WIDTH*LAPI.HEIGHT];
        int count=0;
        int qualityBset=0;
        long ct=System.currentTimeMillis();
        while (isScaning && System.currentTimeMillis()-ct<timeout) {
            sendMsg(MESSAGE_UPDATE_STATUS,"请放置手指");
            int ret = m_cLAPI.GetImage(m_hDevice, m_imageTmp);
            if (ret != LAPI.TRUE) {
                sendMsg(MESSAGE_UPDATE_STATUS,"获取图像失败");
                isScaning = false;
                break;
            }
            ret = m_cLAPI.GetImageQuality(m_hDevice,m_imageTmp);
            if(ret>IMAGE_THRESHOLD){
                count++;
                if(ret>qualityBset){
                    qualityBset=ret;
                    System.arraycopy(m_imageTmp,0,m_imageBest,0,m_imageBest.length);
                }
                if(count==2){
                    byte[] m_itemplate_1 = new byte[LAPI.FPINFO_STD_MAX_SIZE];
                    ret =m_cLAPI.IsPressFinger(m_hDevice,m_imageBest);
                    if (ret==0) {
                        m_itemplate_1=null;
                    }else{
                       ret = m_cLAPI.CreateTemplate(m_hDevice,m_imageBest, m_itemplate_1);
                       if(ret==0)
                           m_itemplate_1=null;
                    }
                    isScaning=false;
                    if(m_itemplate_1==null)
                        sendMsg(MESSAGE_UPDATE_STATUS,"获取指纹图像成功，模板生成失败");
                    else
                        sendMsg(MESSAGE_UPDATE_STATUS,"获取指纹模板成功");
                    if(showFpImage)
                        return new FpFeature(getFingerBitmap(m_imageBest),qualityBset,m_itemplate_1,"");
                    else
                        return new FpFeature(null,qualityBset,m_itemplate_1,"");
                }
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        sendMsg(MESSAGE_UPDATE_STATUS,"获取指纹模板失败");
        return null;
    }

    private Bitmap getFingerBitmap(byte[] image){
        int[] RGBbits = new int[LAPI.WIDTH * LAPI.HEIGHT];
        for (int i = 0; i <LAPI.WIDTH*LAPI.HEIGHT; i++ ) {
            int v;
            if (image != null) v = image[i] & 0xff;
            else v= 0;
            RGBbits[i] = Color.rgb(v, v, v);
        }
        return Bitmap.createBitmap(RGBbits, LAPI.WIDTH,  LAPI.HEIGHT, Bitmap.Config.RGB_565);
    }


    @Override
    public int setFpFeature(int toWhere, byte[] data) {
        try{
            if(data==null)
                return -1;
            //身份证指纹特征值512字节，其他值为自身特征值248字节
            if(data.length==512){
                fingerTemplate=new byte[LAPI.FPINFO_STD_MAX_SIZE];
                System.arraycopy(data,0, fingerTemplate, 0, 512);
                return 0;
            }else if ((data.length==1024)){
                fingerTemplate=new byte[LAPI.FPINFO_STD_MAX_SIZE];
                System.arraycopy(data,0, fingerTemplate, 0, 1024);
            }else {
                return -1;
            }
            return 0;
        }catch (Exception e){
        }
        return -1;
    }

    @Override
    public FpVerifyResult verifyFp(int sThreshold,long timeout) {
        if(!checkOpen()) return null;
        sThreshold=Math.max(sThreshold,VERIFY_THRESHOLD);

        if(fingerTemplate==null){
            sendMsg(MESSAGE_UPDATE_STATUS,"请先调用setFpFeature()!");
            return null;
        }
        FpFeature fpFeature=getFpFeature(false,timeout);
        if(fpFeature==null) return null;
        int score = m_cLAPI.CompareTemplates(m_hDevice,fpFeature.characteristic, fingerTemplate);
        if(score>=sThreshold) {
            sendMsg(MESSAGE_UPDATE_STATUS,"比对成功");
            return new FpVerifyResult(true, score, 0);
        }
        sendMsg(MESSAGE_UPDATE_STATUS,"比对失败");
        return new FpVerifyResult(false, score, 0);
    }

    @Override
    public void cancel() {
        isScaning=false;
        Thread.interrupted();
    }

    @Override
    public int calibration() {
        if(!checkOpen()) return -1;
        return 0;
    }
}
